﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Sims3Package.Interface;

namespace Sims3Package
{
    public class TGIBlock : ITGIblock
    {
        /// <summary>
        /// The instance of entry
        /// </summary>
        public ulong ResourceInstance { get; set; }
        /// <summary>
        /// The type of entry
        /// </summary>
        public uint ResourceType { get; set; }
        /// <summary>
        /// The group of entry
        /// </summary>
        public uint ResourceGroup { get; set; }
        /// <summary>
        /// TGI Order used in paring for wrapper
        /// </summary>
        public TGIOrder Order { get; set; }
        /// <summary>
        /// Initialize a resource entry with given TGI order and a null entry stream in compression
        /// </summary>
        /// <param name="s">Stream that contains TGI information</param>
        /// <param name="order">The sequence of TGI order. e.g. TGI or IGT</param>
        public TGIBlock(Stream s, TGIOrder order)
        {
            this.Order = order;
            BinaryReader r = new BinaryReader(s);
            byte[] byteorder = BitConverter.GetBytes((int)order);
            for (int i = 2; i >=0; i--)
            {
                switch (byteorder[i])
                {
                    case 0x00:
                        this.ResourceType = r.ReadUInt32();
                        break;
                    case 0x01:
                        this.ResourceGroup = r.ReadUInt32();
                        break;
                    case 0x02:
                        this.ResourceInstance = r.ReadUInt64();
                        break;
                }
            }
        }
        /// <summary>
        /// Initialize a resource entry with given TGI order and a null entry stream in compression
        /// </summary>
        /// <param name="r"><see cref="System.IO.BinaryReader"/></param>
        /// <param name="order"><see cref=">Sims3Package.TGIOrder"/></param>
        public TGIBlock(BinaryReader r, TGIOrder order)
        {
            this.Order = order;
            byte[] byteorder = BitConverter.GetBytes((int)order);
            for (int i = 2; i >=0; i--)
            {
                switch (byteorder[i])
                {
                    case 0x00:
                        this.ResourceType = r.ReadUInt32();
                        break;
                    case 0x01:
                        this.ResourceGroup = r.ReadUInt32();
                        break;
                    case 0x02:
                        this.ResourceInstance = r.ReadUInt64();
                        break;
                }
            }
        }
        /// <summary>
        /// Initialize a resource entry with given TGI and a null entry stream in compression
        /// </summary>
        /// <param name="resourcetype">uint of resource type</param>
        /// <param name="resourcegroup">uint of resource group</param>
        /// <param name="resourceinstance">ulong of resource instance</param>
        /// <param name="order">The sequence of TGI order. e.g. TGI or IGT</param>
        public TGIBlock(uint resourcetype, uint resourcegroup, ulong resourceinstance, TGIOrder order)
        {
            this.ResourceType = resourcetype;
            this.ResourceGroup = resourcegroup;
            this.ResourceInstance = resourceinstance;
            this.Order = order;
        }
        /// <summary>
        /// Write TGI info into given stream in specific order
        /// </summary>
        /// <param name="s"><see cref="System.IO.Stream"/></param>
        public void UnParse(Stream s)
        {
            BinaryWriter w = new BinaryWriter(s);
            byte[] byteorder = BitConverter.GetBytes((int)this.Order);
            for (int i = 2; i >= 0; i--)
            {
                switch (byteorder[i])
                {
                    case 0x00:
                        w.Write(this.ResourceType);
                        break;
                    case 0x01:
                        w.Write(this.ResourceGroup);
                        break;
                    case 0x02:
                        w.Write(this.ResourceInstance);
                        break;
                }
            }
        }
        /// <summary>
        /// Shows TGI information in TGI order.
        /// </summary>
        /// <returns>String containing TGI info</returns>
        public override string ToString()
        {
            return string.Format("0x{0:X8}-0x{1:X8}-0x{2:X16}", this.ResourceType, this.ResourceGroup, this.ResourceInstance);
        }

        public override bool Equals(object obj)
        {
            TGIBlock tgi = obj as TGIBlock;
            if (tgi == null) return false;
            return this.ResourceType == tgi.ResourceType && this.ResourceGroup == tgi.ResourceGroup && this.ResourceInstance == tgi.ResourceInstance;
        }

        public override int GetHashCode()
        {
            return this.ResourceType.GetHashCode() & this.ResourceGroup.GetHashCode() & this.ResourceInstance.GetHashCode();
        }
    }
}
